import _ from 'lodash'
import {isMultipleNode} from "../../utils/mutil.js";
import {computed, isReactive, isRef, onMounted, reactive, toRefs, watch} from "vue";

export function useNodeData(modelValue, props, emit) {

  const {
    nvType,
    nvValue,
    nvPath,
    nodeName,
    selectType,
    varDataTree,
    iVarDataTree,
    scopeDataTree,
    // staticDataTree: [],
    itemStaticDataTree,
    itemVarDataTree,
    itemMApiDataTree,
    itemFormDataTree
  } = toRefs(reactive({
    nvType: "iVar",
    nvValue: "",
    nvPath: "",
    nodeName: "",

    selectType: "tree",

    varDataTree: [],
    iVarDataTree: [],
    scopeDataTree: [],
    // staticDataTree: [],
    itemStaticDataTree: [],
    itemVarDataTree: [],
    itemMApiDataTree: [],
    itemFormDataTree: []
  }))

  onMounted(() => {
    init()
    initValue()
  })

  const renderDataTree = computed(() => {
    // console.log(nvType.value, varDataTree.value, iVarDataTree.value, scopeDataTree.value)
    if (nvType.value === 'var') {
      return varDataTree.value;
    } else if (nvType.value === 'iVar') {
      return iVarDataTree.value;
    } else if (nvType.value === 'scope') {
      return scopeDataTree.value;
    }

    return []
  })

  const variables = computed(() => {
    // 当前值，包含 { value, $index, index, row, itemState, state, datas, column, form }
    // scopeDataTree 要添加 scope.xxx , varDataTree 要添加 state.xxx, iVarDataTree 要添加 itemState.xxx
    let vars = [{value: "value", label: "当前选择值", _label: "当前选择值"}, {
      value: "$index",
      label: "当前索引（0开始）",
      _label: "当前索引"
    }];
    let scopeList = _.cloneDeep(scopeDataTree.value);
    let varList = _.cloneDeep(varDataTree.value);
    let iVarList = _.cloneDeep(iVarDataTree.value);

    traverseTree(scopeList, node => {
      node.value = `scope.${node.rela || ""}`;
      node._label = node.value;
      node.prefix = "scope"
    });
    traverseTree(varList, node => {
      node.value = `state.${node.id || ""}`;
      node._label = node.value;
      node.prefix = "state"
    });
    traverseTree(iVarList, node => {
      node.value = `itemState.${node.id || ""}`;
      node._label = node.value;
      node.prefix = "itemState"
    });

    return _.concat(vars, scopeList, varList, iVarList);
  })

  const defExpandKeys = computed(() => {   // 默认展开2层，并且 form & page 默认不展开
    let keys = [];

    if (renderDataTree.value?.length) {
      for (let i = 0; i < renderDataTree.value.length; i++) {
        let node = renderDataTree.value[i];
        let id = node?.id;
        let subs = node?.children;

        if (_isFormPageNode(node)) {
          continue;
        }

        keys.push(id);

        if (subs?.length) {
          for (let j = 0; j < subs.length; j++) {
            let sNode = subs[j];
            let sid = _.get(sNode, "id");
            let sProp = _.get(sNode, "prop");
            if (_isFormPageNode(sNode)) {
              continue;
            }

            keys.push(sid);

            let tsubs = _.get(sNode, "children");

            if (sProp === 'datas' && tsubs && tsubs.length === 1 && tsubs[0].prop === "") {
              keys.push(tsubs[0].id);
            }
          }
        }
      }
    }
    return keys;
  })

  const initValue = (inValue) => {
    let _value = inValue || modelValue.value || "";

    // this.nvValue = newVal;
    if (props.isFormula) {
      // console.log(`------------------> `, _value)
      nvValue.value = _value;
      return;
    }

    // let _value = "";
    let nType = "";
    let nValue = "";
    let nPath = "";

    if (_value) {
      nValue = _value;

      if (_.indexOf(_value, ":") >= 0) {
        let arrs = _value.split(":");
        if (arrs && arrs.length > 1) {
          nType = _.get(arrs, '[0]');
          nValue = _.get(arrs, '[1]')
        }
      }

      if (nvValue && _.indexOf(nvValue, '|') >= 0) {
        let arrs = _value.split("|");
        if (arrs && arrs.length > 1) {
          nValue = _.get(arrs, '[0]');
          nPath = _.get(arrs, '[1]')
        }
      }
    }

    nvType.value = nType || (hasForEleNode() ? "scope" : "iVar");    // !this.isModelNode(this.currentEleData) ?
    nvValue.value = nValue;
    nvPath.value = nPath;
    nodeName.value = _.get(props.currentEleData, "_name");
  }

  const init = () => {
    initVarDataTree();
    initIVarDataTree();
    initScopeDataTree();
  }

  const traverseTree = (nodeList, fn) => {
    if (_.isArray(nodeList) && !_.isEmpty(nodeList)) {
      _.forEach(nodeList, child => {
        // child.prefix = "scope";
        if (typeof fn === 'function') fn(child)
        traverseTree(child.children, fn); // 递归遍历子节点
      });
    } else if (nodeList && !_.isArray(nodeList) && _.isObject(nodeList)) {
      if (typeof fn === 'function') fn(nodeList);
      traverseTree(nodeList.children, fn);
    }
  }

  const _isFormPageNode = (node) => {
    let prop = _.get(node, "prop");
    // let id = _.get(node, "id");
    let subs = _.get(node, "children");
    let fIdx = _.findIndex(subs, {prop: "form_id"});
    let pIdx = _.findIndex(subs, {prop: "pageSize"});

    return (prop === 'form' && fIdx >= 0) || (prop === 'page' && pIdx >= 0);
  }

  const schemaToTree = (schema, parent, propName) => {
    let parentId = _.get(parent, "id") || "";
    let parentRela = _.get(parent, "rela") || "";
    let id = "";
    let rela = "";

    if (propName === '[0]') {
      id = parentId ? `${parentId}${propName}` : propName;
      rela = "";
    } else if (propName) {
      id = parentId ? `${parentId}.${propName}` : propName;
      rela = parentRela ? `${parentRela}.${propName}` : propName;
    }

    let node = {label: _.get(schema, 'title'), id, rela};

    // 保存简要描述信息
    /*if (schema.description) {
        node.description = schema.description;
    }*/

    // 处理类型及其它字段
    switch (schema.type) {
      case "object":
        node.children = [];
        for (let key in schema.properties) {
          let childSchema = schema.properties[key];
          let title = _.get(childSchema, "title") || "";
          let child = schemaToTree(childSchema, node, key);
          let label = key;

          if (title) {
            label = title;
          }

          child.label = label || key;    // `${ childLabel }[${ key }]`;
          child.type = _.get(childSchema, "type");
          child.prop = key;
          node.children.push(child);
        }
        // 处理required属性
        if (schema.required && schema.required.length > 0) {
          node.required = schema.required;
        }
        // form数据树个性化树节点顺序， datas 排第一
        if (_.findIndex(node.children, {prop: 'form'}) >= 0 &&
          _.findIndex(node.children, {prop: 'page'}) >= 0 &&
          _.findIndex(node.children, {prop: 'datas'}) >= 0) {
          // 将 datas提前
          let dIdx = _.findIndex(node.children, {prop: 'datas'});

          if (dIdx > 0) {
            let dArr = node.children.splice(dIdx, 1);
            node.children = _.concat(dArr, node.children);
          }
        }
        break;
      case "array":
        if(!schema.items) break;
        if (!schema.items.type) schema.items.type = 'object';
        let child = schemaToTree(schema.items, node, '[0]');

        child.label = `行记录`;
        child.type = _.get(schema.items, "type");
        child.prop = "";
        node.children = [child];
        node.type = "array";
        break;
      default:
        node.type = schema.type;
        break;
    }

    return node;
  }

  const initVarDataTree = () => {
    let varDtTree = [];
    let vars = _.get(props.page, "vars");
    let varVals = {};

    if (vars?.length) {
      for (let i = 0; i < vars?.length; i++) {
        let iv = vars[i];
        let prop = _.get(iv, "prop");
        if (prop) {
          varVals[prop] = _.get(props.dataset, `state.${prop}`);
        }
      }

      let varSchema = $utils.createSchema(varVals);
      let root = schemaToTree(varSchema);

      varDtTree = _.get(root, "children", []);
    }

    varDataTree.value = varDtTree;
  }

  const initIVarDataTree = () => {
    let iVarDtTree = [];
    let vars = _.get(props.item, "vars");
    let varVals = {};
    let itemCode = _.get(props.item, "alias") || _.get(props.item, "page_item_code");

    if (vars?.length) {
      for (let i = 0; i < vars.length; i++) {
        let iv = vars[i];
        let prop = _.get(iv, "prop");
        if (prop) {
          varVals[prop] = _.get(props.dataset, `items.${itemCode}.${prop}`);
        }
      }

      // console.log(JSON.stringify(varVals), typeof varVals, isRef(varVals), isReactive(varVals))

      let varSchema = $utils.createSchema(varVals);
      let root = schemaToTree(varSchema);

      iVarDtTree = _.get(root, "children", []);
    }

    iVarDataTree.value = iVarDtTree;
  }

  const initScopeDataTree = () => {
    // 获取最近的 multiple 节点
    let code = _.get(props.currentEleData, "_code");

    if (!code) return;

    let nodeParents = $utils.getTreePath(code, props.elemNodes, 'code', 'children', true);
    let multiNodes = _.filter(nodeParents, np => isMultipleNode(_.get(np, "def")));
    let renderTree = [];

    if (multiNodes?.length) {
      let realRenderTree = renderTree;

      for (let i = 0; i < multiNodes.length; i++) {
        let mn = multiNodes[i];
        let value = _.get(mn, `def._value`);
        // let nvType = "scope";
        let nvValue = "";

        if(mn?.def?._type === 'JzlList') {  // 兼容 JzlList dataPath 配置在 _ext 的情况
          value = mn?.def?._ext?.dataPath;
        }
        // console.log(`--------------> value: `, value, realRenderTree)

        if (value) {
          nvValue = value;

          if (_.indexOf(value, ":") >= 0) {
            let arrs = _.split(value, ":");
            let parentNvType = _.get(arrs, "[0]");
            nvValue = _.get(arrs, "[1]");

            if (parentNvType === 'var') {
              realRenderTree = varDataTree.value
            } else {
              realRenderTree = iVarDataTree.value
            }
          } else {
            realRenderTree = iVarDataTree.value
          }

          let subTreeNode = $utils.getTreeData(realRenderTree, "rela", nvValue);

          if (subTreeNode) {
            realRenderTree = [subTreeNode];
          } else {
            realRenderTree = [];
            break;
          }
        }
      }

      scopeDataTree.value = realRenderTree;
    }
  }

  const hasForEleNode = () => {
    let code = _.get(props.currentEleData, "_code");
    let nodeParents = $utils.getTreePath(code, props.elemNodes, 'code', 'children', true);
    let multiNodes = _.filter(nodeParents, np => isMultipleNode(_.get(np, "def")));

    return multiNodes && multiNodes.length > 0;
  }

  const handleSelectTreePath = (data) => {
    let type = data?.type;
    let isMultiple = props.multiple || isMultipleNode(props.currentEleData)

    if (isMultiple && type !== 'array') {
      $jui.toast("循环节点，需选择 [ array ] 类型数据。");

      // 忽略数据类型检查
      if(!props.ignoreCheckDataType) return;
    } else if (!isMultiple && type === 'array') {
      $jui.toast("普通节点，不支持 [ array ] 类型数据。");

      if(!props.ignoreCheckDataType) return;
    }

    let val = "";

    if (nvType.value === 'scope') {
      if (hasForEleNode()) {
        val = _.get(data, "rela");
      } else {
        val = _.get(data, "id");

        let datasPathDef = _.get(props.item, 'data_fieldsmap._rowsPath');

        if (!datasPathDef) {
          datasPathDef = "datas";
        }

        if (val) val = val.replace(new RegExp(`^${ datasPathDef }`), "");
        // 去除默认的 datas
      }
    } else {
      val = _.get(data, "id");
    }

    if (val) nvValue.value = val;

    // this.handleChgNv();
  }

  watch(() => modelValue.value, (_value) => {
    initValue();
  })

  watch(() => nvValue.value, (val) => {
    if (props.isFormula) {
      modelValue.value = val;
      // this.$emit('change', val);
    } else {
      let fullValue = val;
      if (nvType.value && fullValue) fullValue = `${nvType.value}:${val}`;
      modelValue.value = fullValue;
      // this.$emit('change', fullValue);
    }
  })

  watch(() => props.item, () => {
    init()
  }, {deep: true})

  watch(() => props.dataset, () => {
    // console.log(`------> props.dataset change ...`)
    init();
  }, {deep: true})

  watch(() => props.currentEleData?._code, () => {
    initValue()
    initScopeDataTree()
  })

  // TODO 暂时
  /*watch(() => nodeName.value, (name) => {
    if (props.currentEleData) {
      props.currentEleData._name = name;
      if (props.currentNode && !props.currentNode.isRoot) {
        props.currentNode.name = name;
      }
    }
  })*/

  return {
    nvType,
    nvValue,
    nvPath,
    nodeName,
    selectType,
    varDataTree,
    iVarDataTree,
    scopeDataTree,
    renderDataTree,
    // staticDataTree: [],
    itemStaticDataTree,
    itemVarDataTree,
    itemMApiDataTree,
    itemFormDataTree,
    defExpandKeys,

    initValue,
    init,
    traverseTree,

    _isFormPageNode,
    schemaToTree,
    initVarDataTree,
    initIVarDataTree,
    initScopeDataTree,
    hasForEleNode,
    handleSelectTreePath
  }
}

export const useNodeDataProps = {
  item: Object,
  page: Object,
  currentEleData: Object,
  // form: Object,
  currentNode: Object,
  elemNodes: [Array],
  dataset: Object,
  multiple: false,
  isFormula: false,
  ignoreCheckDataType: false
}
